import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { MODULE_NAME, getOrganizing } from './redux';
import { Icon } from '@/components';
import { Tree, Spin } from 'antd';
import { union } from '@/utils';
import type { RootState } from '@/store';
import type { IOrganizingData, IOrganizingProp, IOrganizingType } from './index.d';

const { DirectoryTree } = Tree;

const iconMap = {
  'corp': <Icon type="icon-zhinengjigou" />,
  'school': <Icon type="icon-school" />,
  'grade': <Icon type="icon-grade" />,
  'gradeClass': <Icon type="icon-class" />
}

// 递归数据 如果匹配上关键字 给关键字添加className=site-tree-search-value
const loop = (data: IOrganizingData[], keyword: string, type: IOrganizingType, leave: number = 1) => data.map((item: IOrganizingData): any => {
  const index = item.label.indexOf(keyword);
  const beforeStr = item.label.substr(0, index);
  const afterStr = item.label.substr(index + keyword.length);

  const title: JSX.Element =
    index > -1 ? (
      <span>
        {beforeStr}
        <span className="site-tree-search-value">{keyword}</span>
        {afterStr}
      </span>
    ) : (
        <span>{item.label}</span>
      );
  const nodeType: any = item.attribute.nodeType || item.attribute.type;
  if (item.children && item.children.length) {
    return { title, key: item.id, nodeType: nodeType, attribute: item.attribute, icon: iconMap[nodeType], children: loop(item.children, keyword, type, leave + 1) };
  }
  return {
    title,
    key: item.id,
    nodeType: nodeType,
    attribute: item.attribute,
    icon: iconMap[nodeType]
  };
})

// 查询父级节点的key
const getParentKey = (key: string, tree: IOrganizingData[]): string => {
  let parentKey: string = '';
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i];
    if (node.children && node.children.length) {
      if (node.children.some(item => item.id === key)) {
        parentKey = node.id;
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children);
      }
    }
  }
  return parentKey;
};

let unionTreeData: IOrganizingData[] = [];
let defaultExpandedKey: string = '';

const Organizing: React.FC<IOrganizingProp> = React.memo(({ keyword, handleClickNode, type = 'class' }) => {
  const dispath = useDispatch();
  const [expandedKeys, setExpandedKeys] = useState<string[]>([])
  const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
  const [loading, setLoading] = useState<boolean>(false);
  const treeData = useSelector<RootState, IOrganizingData[]>(state => state[MODULE_NAME].treeData)
  // 树节点选中反馈
  const onSelect = (keys: React.Key[], e: any) => {
    handleClickNode && handleClickNode(keys, e.node)
  };

  // 展开关闭树某一个节点设置keys
  const onExpand = (expandedKeys: any[]) => {
    setExpandedKeys(expandedKeys)
    setAutoExpandParent(false)
  };

  // 设置展开项
  const handleSetExpandedKeys = () => {
    const keys: any[] = keyword ? unionTreeData.map(item => {
      if (item.label.indexOf(keyword) > -1) {
        return getParentKey(item.id, treeData);
      }
      return null;
    }).filter((item, i, self) => item && self.indexOf(item) === i) : [defaultExpandedKey];
    setAutoExpandParent(true)
    setExpandedKeys(keys)
  }

  // 获取组织机构数据
  const getOrganizingData = async () => {
    try {
      setLoading(true)
      await dispath(getOrganizing(type))
    } catch { }
    setLoading(false)
  }
  useEffect(() => {
    getOrganizingData()
  }, [])

  // 组织机构树数据发生变化 设置展开项 并且设置展开的组织机构数据
  useEffect(() => {
    unionTreeData = union(treeData);
    if (treeData.length === 1) {
      defaultExpandedKey = treeData[0].id;
      setExpandedKeys([defaultExpandedKey])
    }
  }, [treeData])

  // 搜索值变化设置展开项
  useEffect(() => {
    handleSetExpandedKeys()
  }, [keyword])

  return (
    <Spin tip="加载中..." spinning={loading}>
      <DirectoryTree
        expandedKeys={expandedKeys}
        autoExpandParent={autoExpandParent}
        expandAction={false}
        onSelect={onSelect}
        onExpand={onExpand}
        treeData={loop(treeData, keyword, type)}
      />
    </Spin>
  )
}, (prevProps: IOrganizingProp, nextProps: IOrganizingProp) => {
  return prevProps.keyword === nextProps.keyword ? true : false;
})

export default Organizing
